package com.yixing.tech.system.controller;

import com.mongodb.MongoNamespace;
import com.mongodb.client.model.RenameCollectionOptions;
import com.yixing.tech.common.base.*;
import com.yixing.tech.common.service.CommonService;
import com.yixing.tech.common.vo.s3.DictVO;
import com.yixing.tech.common.vo.s3.WebPageVO;
import com.yixing.tech.common.vo.s5.EntitySchema;
import com.yixing.tech.entity.entity.ObjStatus;
import com.yixing.tech.system.service.EntityManagerService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

import static com.yixing.tech.common.security.context.UserContext.getTenantId;

/**
 * @author yixing tech
 */
@RestController
@CrossOrigin
@RequestMapping(value = "/obj")
public class EntityManagerController extends BaseControl {

    @Autowired
    private EntityManagerService entityManagerService;

    @Resource
    MongoTemplate mongoTemplate;

    @Autowired
    private CommonService commonService;

    @PostMapping("/insert")
    public Rs<Object> save(@RequestBody EntitySchema map) throws BusinessException {
        commonService.fillCreateUser(map);
        entityManagerService.add(map);
        return Rs.ok();
    }

    @PostMapping("/clone")
    public Rs<Object> clone(@RequestBody EntitySchema map) throws BusinessException {
        commonService.fillCreateUser(map);
        entityManagerService.cloneObj(map);
        return Rs.ok();
    }

    @PostMapping("/listPage")
    public Rs<Object> listPage(@RequestBody PageRow<ConditionsVO> vo) throws BusinessException {
        vo.getCondition(ConditionsVO.class).setTenantId(getTenantId());
        return Rs.ok(entityManagerService.listPage(vo));
    }

    @PostMapping("/list")
    public Rs<Object> list(@RequestBody ConditionsVO vo) throws BusinessException {
        vo.setTenantId(getTenantId());
        return Rs.ok(entityManagerService.list(vo));
    }

    @PostMapping("/update/{id}")
    public Rs<Object> update(@PathVariable String id, @RequestBody EntitySchema map) throws BusinessException {
        commonService.fillUpdateUser(map);
        map.setId(id);
        entityManagerService.update(map);
        return Rs.ok();
    }

    @PostMapping("/status")
    public Rs<Object> status(@RequestBody EntitySchema map) throws BusinessException {
        commonService.fillUpdateUser(map);
        entityManagerService.update(map);
        return Rs.ok();
    }

    @GetMapping("/reset/{id}")
    public Rs<Object> reset(@PathVariable String id) throws BusinessException {
        EntitySchema vo = new EntitySchema();
        vo.setId(id);
        vo.setStatus(ObjStatus.deft.name());
        commonService.fillUpdateUser(vo);
        entityManagerService.update(vo);
        return Rs.ok();
    }

    @DeleteMapping("/{id}")
    public Rs<Object> delete(@PathVariable String id) throws BusinessException {
        entityManagerService.deleteById(id);
        return Rs.ok();
    }

    @GetMapping("/{id}")
    public Rs<Object> get(@PathVariable String id) throws BusinessException {
        return Rs.ok(entityManagerService.queryById(id, commonService.getApiUser()));
    }

    @GetMapping("/added/{id}")
    public Rs<Object> added(@PathVariable String id) throws BusinessException {
        EntitySchema objVO = new EntitySchema();
        commonService.fillCreateUser(objVO);
        objVO.setId(id);
        entityManagerService.addedObj(objVO);
        return Rs.ok();
    }

    @GetMapping("/added")
    public Rs<Object> added() throws BusinessException {
        entityManagerService.addedObj();
        return Rs.ok();
    }

    @PostMapping("{objId}/config/{type}/save")
    public Rs<Object> saveConfig(@PathVariable String objId, @PathVariable String type, @RequestBody List<EntitySchema.AttrConfig> list) throws BusinessException {
        entityManagerService.saveOrUpdateConfig(objId, type, list);
        return Rs.ok();
    }

    @GetMapping("/{id}/config/{type}")
    public Rs<Object> getConfig(@PathVariable String id, @PathVariable String type) throws BusinessException {
        return Rs.ok(entityManagerService.getConfig(id, type));
    }


    @GetMapping("/test")
    public Rs<Object> test() throws BusinessException {
        Set<String> tables = mongoTemplate.getCollectionNames();
        String dbName = mongoTemplate.getDb().getName();
        for (String name : tables) {
            if (!name.startsWith("entity")) continue;
            System.out.println("------:" + name);
            String code = name.split("_")[2];
            EntitySchema cond = new EntitySchema();
            cond.setCode(code);
            cond = mongoTemplate.findOne(Query.query(Criteria.where("code").is(code)), EntitySchema.class, "obj");
            if (cond == null || !StringUtils.hasText(cond.getId())) continue;
            mongoTemplate.getCollection(name).renameCollection(new MongoNamespace(dbName + ".entity_" + cond.getId()), new RenameCollectionOptions().dropTarget(true));
        }
        return Rs.ok();
    }

    @GetMapping("/test2")
    public Rs<Object> test2() throws BusinessException {
        List<WebPageVO> list = mongoTemplate.findAll(WebPageVO.class, "webPage");
        for (WebPageVO obj : list) {
            DictVO dict = obj.getType();
            if (dict == null) continue;
            if ("624e5135a6b9f60c62bc2b9b".equals(dict.getId())) {
                String code = obj.getUri();
                EntitySchema cond = new EntitySchema();
                cond.setCode(code);
                cond = mongoTemplate.findOne(Query.query(Criteria.where("code").is(code)), EntitySchema.class, "obj");
                if (cond == null || !StringUtils.hasText(cond.getId())) continue;

                Query query = new Query();
                query.addCriteria(Criteria.where("_id").is(new ObjectId(obj.getId())));
                Update update = new Update();
                try {
                    update.set("uri", cond.getId());
                    mongoTemplate.upsert(query, update, "webPage");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return Rs.ok();
    }

    @GetMapping("/test1")
    public Rs<Object> test1() throws BusinessException {
        List<EntitySchema> list = entityManagerService.list(new EntitySchema());
        for (EntitySchema obj : list) {
            List<EntitySchema.AttrVO> attrs = obj.getAttrs();
            if (attrs == null) continue;
            boolean needEditor = false;
            for (EntitySchema.AttrVO attr : attrs) {
                if ("obj".equals(attr.getType())) {
                    String code = attr.getReference().toString();
                    EntitySchema cond = new EntitySchema();
                    cond.setCode(code);
                    cond = mongoTemplate.findOne(Query.query(Criteria.where("code").is(code)), EntitySchema.class, "obj");
                    if (cond == null || !StringUtils.hasText(cond.getId())) continue;
                    attr.setReference(cond.getId());
                    needEditor = true;
                }
            }
            if (needEditor) {
                entityManagerService.update(obj);
            }
        }
        return Rs.ok();
    }

}
